// Licensed to the LF AI & Data foundation under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <string>
#include <memory>
#include <utility>

#include <oneapi/tbb/concurrent_queue.h>

#include "common/FieldDataInterface.h"
#include "common/Channel.h"
#include "common/ArrowDataWrapper.h"

namespace milvus {

// 标量类型字段数据模板类，继承自FieldDataImpl
// 用于存储标量类型的数据，如整数、浮点数、布尔值等
template <typename Type>
class FieldData : public FieldDataImpl<Type, true> {
 public:
    // 静态断言确保模板参数是标量类型或主键类型
    static_assert(IsScalar<Type> || std::is_same_v<Type, PkType>);
    
    // 构造函数：根据数据类型、是否可为空以及缓冲行数创建FieldData对象
    explicit FieldData(DataType data_type,
                       bool nullable,
                       int64_t buffered_num_rows = 0)
        : FieldDataImpl<Type, true>::FieldDataImpl(
              1, data_type, nullable, buffered_num_rows) {
    }
    
    // 静态断言确保模板参数是标量类型或主键类型
    static_assert(IsScalar<Type> || std::is_same_v<Type, PkType>);
    
    // 构造函数：根据数据类型、是否可为空以及预定义的数据创建FieldData对象
    explicit FieldData(DataType data_type,
                       bool nullable,
                       FixedVector<Type>&& inner_data)
        : FieldDataImpl<Type, true>::FieldDataImpl(
              1, data_type, nullable, std::move(inner_data)) {
    }
};

// std::string类型的特化模板类，继承自FieldDataStringImpl
// 用于存储字符串类型的字段数据
template <>
class FieldData<std::string> : public FieldDataStringImpl {
 public:
    // 静态断言确保模板参数是标量类型或主键类型
    static_assert(IsScalar<std::string> || std::is_same_v<std::string, PkType>);
    
    // 构造函数：根据数据类型、是否可为空以及缓冲行数创建字符串类型的FieldData对象
    explicit FieldData(DataType data_type,
                       bool nullable,
                       int64_t buffered_num_rows = 0)
        : FieldDataStringImpl(data_type, nullable, buffered_num_rows) {
    }
};

// Json类型的特化模板类，继承自FieldDataJsonImpl
// 用于存储JSON类型的字段数据
template <>
class FieldData<Json> : public FieldDataJsonImpl {
 public:
    // 静态断言确保模板参数是标量类型或主键类型
    static_assert(IsScalar<std::string> || std::is_same_v<std::string, PkType>);
    
    // 构造函数：根据数据类型、是否可为空以及缓冲行数创建JSON类型的FieldData对象
    explicit FieldData(DataType data_type,
                       bool nullable,
                       int64_t buffered_num_rows = 0)
        : FieldDataJsonImpl(data_type, nullable, buffered_num_rows) {
    }
};

// Array类型的特化模板类，继承自FieldDataArrayImpl
// 用于存储数组类型的字段数据
template <>
class FieldData<Array> : public FieldDataArrayImpl {
 public:
    // 静态断言确保模板参数是标量类型或主键类型
    static_assert(IsScalar<Array> || std::is_same_v<std::string, PkType>);
    
    // 构造函数：根据数据类型、是否可为空以及缓冲行数创建数组类型的FieldData对象
    explicit FieldData(DataType data_type,
                       bool nullable,
                       int64_t buffered_num_rows = 0)
        : FieldDataArrayImpl(data_type, nullable, buffered_num_rows) {
    }
};

// VectorArray类型的特化模板类，继承自FieldDataVectorArrayImpl
// 用于存储向量数组类型的字段数据
template <>
class FieldData<VectorArray> : public FieldDataVectorArrayImpl {
 public:
    // 构造函数：根据数据类型以及缓冲行数创建向量数组类型的FieldData对象
    explicit FieldData(DataType data_type, int64_t buffered_num_rows = 0)
        : FieldDataVectorArrayImpl(data_type, buffered_num_rows) {
    }

    // 获取维度的虚函数实现，VectorArray类型不支持获取维度操作
    int64_t
    get_dim() const override {
        ThrowInfo(Unsupported,
                  "Call get_dim on FieldData<VectorArray> is not supported");
    }
};

// FloatVector类型的特化模板类，继承自FieldDataImpl<float, false>
// 用于存储浮点型向量数据
template <>
class FieldData<FloatVector> : public FieldDataImpl<float, false> {
 public:
    // 构造函数：根据维度、数据类型以及缓冲行数创建浮点型向量的FieldData对象
    explicit FieldData(int64_t dim,
                       DataType data_type,
                       int64_t buffered_num_rows = 0)
        : FieldDataImpl<float, false>::FieldDataImpl(
              dim, data_type, false, buffered_num_rows) {
    }
};

// BinaryVector类型的特化模板类，继承自FieldDataImpl<uint8_t, false>
// 用于存储二进制向量数据
template <>
class FieldData<BinaryVector> : public FieldDataImpl<uint8_t, false> {
 public:
    // 构造函数：根据维度、数据类型以及缓冲行数创建二进制向量的FieldData对象
    // 注意：二进制向量的维度必须是8的倍数
    explicit FieldData(int64_t dim,
                       DataType data_type,
                       int64_t buffered_num_rows = 0)
        : FieldDataImpl(dim / 8, data_type, false, buffered_num_rows),
          binary_dim_(dim) {
        Assert(dim % 8 == 0);
    }

    // 获取维度的虚函数实现，返回二进制向量的真实维度
    int64_t
    get_dim() const override {
        return binary_dim_;
    }

 private:
    // 存储二进制向量的真实维度
    int64_t binary_dim_;
};

// Float16Vector类型的特化模板类，继承自FieldDataImpl<float16, false>
// 用于存储半精度浮点型向量数据
template <>
class FieldData<Float16Vector> : public FieldDataImpl<float16, false> {
 public:
    // 构造函数：根据维度、数据类型以及缓冲行数创建半精度浮点型向量的FieldData对象
    explicit FieldData(int64_t dim,
                       DataType data_type,
                       int64_t buffered_num_rows = 0)
        : FieldDataImpl<float16, false>::FieldDataImpl(
              dim, data_type, false, buffered_num_rows) {
    }
};

// BFloat16Vector类型的特化模板类，继承自FieldDataImpl<bfloat16, false>
// 用于存储脑浮点型向量数据
template <>
class FieldData<BFloat16Vector> : public FieldDataImpl<bfloat16, false> {
 public:
    // 构造函数：根据维度、数据类型以及缓冲行数创建脑浮点型向量的FieldData对象
    explicit FieldData(int64_t dim,
                       DataType data_type,
                       int64_t buffered_num_rows = 0)
        : FieldDataImpl<bfloat16, false>::FieldDataImpl(
              dim, data_type, false, buffered_num_rows) {
    }
};

// SparseFloatVector类型的特化模板类，继承自FieldDataSparseVectorImpl
// 用于存储稀疏向量数据
template <>
class FieldData<SparseFloatVector> : public FieldDataSparseVectorImpl {
 public:
    // 构造函数：根据数据类型以及缓冲行数创建稀疏向量的FieldData对象
    explicit FieldData(DataType data_type, int64_t buffered_num_rows = 0)
        : FieldDataSparseVectorImpl(data_type, buffered_num_rows) {
    }
};

// Int8Vector类型的特化模板类，继承自FieldDataImpl<int8, false>
// 用于存储8位整型向量数据
template <>
class FieldData<Int8Vector> : public FieldDataImpl<int8, false> {
 public:
    // 构造函数：根据维度、数据类型以及缓冲行数创建8位整型向量的FieldData对象
    explicit FieldData(int64_t dim,
                       DataType data_type,
                       int64_t buffered_num_rows = 0)
        : FieldDataImpl<int8, false>::FieldDataImpl(
              dim, data_type, false, buffered_num_rows) {
    }
};

// 定义字段数据指针类型别名
using FieldDataPtr = std::shared_ptr<FieldDataBase>;

// 定义字段数据通道类型别名
using FieldDataChannel = Channel<FieldDataPtr>;

// 定义字段数据通道指针类型别名
using FieldDataChannelPtr = std::shared_ptr<FieldDataChannel>;

// 初始化标量类型字段数据的函数声明
// 根据数据类型、是否可为空以及容量行数创建标量字段数据对象
FieldDataPtr
InitScalarFieldData(const DataType& type, bool nullable, int64_t cap_rows);

}  // namespace milvus